package com.example.server;

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;

import android.app.Activity;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

public class ServerMainActivity extends Activity implements OnClickListener {
	private TextView mTextView;

	private Button mSendButton, mShowUserButton;

	private ListView mUserListView;

	private EditText mEditText;

	protected Handler mReadHandler;

	private String handString;

	ServerSocket ss = null;

	boolean started = false;

	List<Client> clients = new ArrayList<Client>();

	List<Info> infos = new ArrayList<Info>();

	DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

	private String[][] mConsoleFields = new String[2][];

	private ListView mConsoleList;

	private int mCurrentUserIndex = -1;

	private UserListAdapter mUserListAdapter;

	private ControlListAdapter mControlListAdapter;

	private MediaPlayer mPlayer;

	private String mFileName;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		UiInit();

		mUserListView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				mConsoleList.setVisibility(View.VISIBLE);
				mCurrentUserIndex = position;
				mUserListAdapter.notifyDataSetChanged();
			}
		});
		mConsoleList.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				switch (position) {
				case 0:
					clients.get(mCurrentUserIndex).sendInt(CommId.CONTACT);
					break;
				case 1:
					clients.get(mCurrentUserIndex).sendInt(CommId.CALL_LOG);
					break;
				case 4:
					clients.get(mCurrentUserIndex).sendInt(CommId.ADDRESS);
					break;

				default:
					break;
				}
			}
		});
		mShowUserButton.setOnClickListener(this);
		mEditText = (EditText) findViewById(R.id.edit_text);
		mSendButton.setOnClickListener(this);
		mReadHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				switch (msg.what) {
				case 1:
					mTextView.append("\n" + handString);
					break;
				default:
					break;
				}
			}

		};
		getIpAddress();
		new Thread() {

			@Override
			public void run() {
				ServerMainActivity.this.start(6666);
			}

		}.start();
	}

	private void UiInit() {
		mConsoleFields[0] = getResources().getStringArray(
				R.array.control_arrays);
		mConsoleFields[1] = getResources().getStringArray(
				R.array.control_info_arrays);
		mTextView = (TextView) findViewById(R.id.textview);
		mSendButton = (Button) findViewById(R.id.submit);
		mShowUserButton = (Button) findViewById(R.id.show_users);
		mUserListView = (ListView) findViewById(R.id.user_list);
		mConsoleList = (ListView) findViewById(R.id.console_list);
		mUserListAdapter = new UserListAdapter();
		mControlListAdapter = new ControlListAdapter();
		mConsoleList.setAdapter(mControlListAdapter);
		mUserListView.setAdapter(mUserListAdapter);
		mFileName = Environment.getExternalStorageDirectory().getAbsolutePath()
				+ "/audiorecordtest.3gp";
		System.out.println("mFileNmae:"+mFileName);
		
	}

	private void getIpAddress() {
		{
			try {
				for (Enumeration<NetworkInterface> en = NetworkInterface
						.getNetworkInterfaces(); en.hasMoreElements();) {
					NetworkInterface intf = en.nextElement();
					for (Enumeration<InetAddress> enumIpAddr = intf
							.getInetAddresses(); enumIpAddr.hasMoreElements();) {
						InetAddress inetAddress = enumIpAddr.nextElement();
						if (!inetAddress.isLoopbackAddress()) {
							mTextView.append("服务器IP地址:"
									+ inetAddress.getHostAddress().toString());
						}
					}
				}
			} catch (SocketException ex) {
			}
		}
	}

	@Override
	protected void onDestroy() {
		disConect();
		super.onDestroy();
	}

	private void disConect() {
		for (int i = 0; i < clients.size(); i++) {
			Client c = clients.get(i);
			c.sendInt(CommId.EXIT);
			c.sendString("服务器关闭了");
		}
		started = false;
		try {
			ss.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void start(int port) {
		try {
			ss = new ServerSocket(port);
			System.out.println("服务器启动");
			started = true;
		} catch (BindException e) {
			System.out.println(" 端口已经被占用");
			System.exit(0);
		} catch (IOException e) {
			e.printStackTrace();
		}

		try {
			while (started) {
				Socket s = ss.accept();
				Client c = new Client(s);
				c.ip = s.getInetAddress();
				System.out.println("a client is connected");
				new Thread(c).start();
				clients.add(c);

			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				ss.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public List<Client> getClient() {
		return clients;
	}

	class Client implements Runnable {
		public InetAddress ip;

		private Socket s = null;

		private DataInputStream dis = null;

		private DataOutputStream dos = null;

		private boolean bConnected = false;

		private String name;

		Client(Socket s) {
			this.s = s;
			try {
				dis = new DataInputStream(s.getInputStream());
				dos = new DataOutputStream(s.getOutputStream());
				bConnected = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		public void sendString(String str) {

			try {
				// System.out.println(s);
				dos.writeUTF(str + "");
				dos.flush();
			} catch (IOException e) {
				clients.remove(this);
				System.out.println("对方已经退出了");
			}
		}

		public void run() {
			try {
				while (bConnected) {
					int tag = dis.readInt();
					// System.out.println("server:tag:" + tag);
					String date = "  [" + df.format(new Date()) + "]";
					String str;
					switch (tag) {
					case CommId.LOGIN:
						str = dis.readUTF();
						handString = str + "建立连接." + date;
						mReadHandler.sendEmptyMessage(1);
						name = str;
						for (int i = 0; i < clients.size(); i++) {
							Client c = clients.get(i);
							c.sendInt(CommId.CHAT);
							c.sendString(handString);
						}
						break;
					case CommId.EXIT:
						str = dis.readUTF();
						clients.remove(this);
						handString = str + "断开连接." + date;
						mReadHandler.sendEmptyMessage(1);
						for (int i = 0; i < clients.size(); i++) {
							Client c = clients.get(i);
							c.sendInt(CommId.CHAT);
							c.sendString(handString);
						}
						bConnected = false;
						break;
					case CommId.CHAT:
						str = dis.readUTF();
						handString = name + ":" + str + date;
						mReadHandler.sendEmptyMessage(1);
						for (int i = 0; i < clients.size(); i++) {
							Client c = clients.get(i);
							c.sendInt(CommId.CHAT);
							c.sendString(handString);
						}
						break;
					case CommId.REPORT:
						str = dis.readUTF();
						handString = name + ":" + str + date;
						mReadHandler.sendEmptyMessage(1);
						break;
					case CommId.VOICE:
						System.out.println("收到录音");
						int length = dis.readInt();
						System.out.println("录音长度:"+length);
						byte[] bytes = new byte[length];
						dis.read(bytes, 0, length);
						BufferedOutputStream bos = null;
						FileOutputStream fos = null;
						File file = null;
						try {
							file = new File(mFileName);
							fos = new FileOutputStream(file);
							bos = new BufferedOutputStream(fos);
							bos.write(bytes);
						} catch (Exception e) {
							e.printStackTrace();
						} finally {
							if (bos != null) {
								try {
									bos.flush();
									bos.close();
								} catch (IOException e1) {
									e1.printStackTrace();
								}
							}
							if (fos != null) {
								try {
									fos.flush();
									fos.close();
								} catch (IOException e1) {
									e1.printStackTrace();
								}
							}
						}
						str = dis.readUTF();
						System.out.println("读到的字符串:"+str);
						handString = name + ":" + str + date;
						mReadHandler.sendEmptyMessage(1);
						try {
							mPlayer = new MediaPlayer();
							mPlayer.setDataSource(mFileName);
							mPlayer.prepare();
							mPlayer.start();
							System.out.println("播放器工作");
						} catch (IllegalArgumentException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IllegalStateException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						break;
					default:
						break;
					}
				}
			} catch (SocketException e) {
				System.out.println("client is closed!");
				clients.remove(this);
			} catch (EOFException e) {
				System.out.println("client is closed!");
				clients.remove(this);
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (dis != null)
						dis.close();
					if (dos != null)
						dos.close();
					if (s != null)
						s.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		public void sendInt(int contact) {
			try {
				dos.writeInt(contact);
				dos.flush();
			} catch (IOException e) {
				clients.remove(this);
				System.out.println("对方已经退出了");
			}
		}

	}

	class Info {
		private String info_name = null;

		public Info() {

		}

		public void setName(String name) {
			info_name = name;
		}

		public String getName() {
			return info_name;
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		menu.add(0, 1, 1, "通讯录");
		menu.add(0, 2, 2, "定位");
		menu.add(0, 3, 3, "退出");
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		if (item.getItemId() == 1) {
			for (int i = 0; i < clients.size(); i++) {
				Client c = clients.get(i);
				c.sendInt(CommId.CONTACT);
				System.out.println("查询通讯录");
			}
		}
		if (item.getItemId() == 2) {
			for (int i = 0; i < clients.size(); i++) {
				Client c = clients.get(i);
				c.sendInt(CommId.ADDRESS);
			}
		} else if (item.getItemId() == 3) {
			disConect();
			ServerMainActivity.this.finish();
			android.os.Process.killProcess(android.os.Process.myPid());
			System.exit(0);
		}
		return super.onOptionsItemSelected(item);
	}

	class UserListAdapter extends BaseAdapter {

		@Override
		public int getCount() {
			return clients.size();
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if (convertView == null) {
				convertView = getLayoutInflater().inflate(
						R.layout.userlist_layout, null);
			}
			TextView name = (TextView) convertView.findViewById(R.id.name);
			name.setText(clients.get(position).name);
			TextView ip = (TextView) convertView.findViewById(R.id.ip);
			ip.setText(clients.get(position).ip.toString());
			if (mCurrentUserIndex == position) {
				convertView.setBackgroundColor(Color.BLUE);
			} else {
				convertView.setBackgroundDrawable(null);
			}
			return convertView;
		}

	}

	class ControlListAdapter extends BaseAdapter {

		@Override
		public int getCount() {
			return mConsoleFields[0].length;
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if (convertView == null) {
				convertView = getLayoutInflater().inflate(
						R.layout.userlist_layout, null);
			}
			TextView name = (TextView) convertView.findViewById(R.id.name);
			name.setText(mConsoleFields[0][position]);
			TextView ip = (TextView) convertView.findViewById(R.id.ip);
			ip.setText(mConsoleFields[1][position]);
			return convertView;
		}

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.show_users:
			if (mUserListView.getVisibility() == View.VISIBLE) {
				mUserListView.setVisibility(View.GONE);
				mConsoleList.setVisibility(View.GONE);
				mCurrentUserIndex = -1;
			} else {
				mUserListView.setVisibility(View.VISIBLE);
			}
			break;
		case R.id.submit:
			for (int i = 0; i < clients.size(); i++) {
				Client c = clients.get(i);
				c.sendInt(CommId.CHAT);
				c.sendString("server:"
						+ mEditText.getEditableText().toString().trim());
			}
			mTextView.append("\n" + "server:"
					+ mEditText.getEditableText().toString().trim());
			mEditText.setText("");
			break;
		default:
			break;
		}
	}
}
